package me.android.library.starters.http;

import android.app.Activity;
import android.app.DownloadManager;
import android.app.DownloadManager.Request;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Environment;
import android.webkit.MimeTypeMap;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;

import java.util.Objects;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import me.android.library.utils.android.InstallUtil;
import me.android.library.utils.android.PermissionUtil;
import me.android.library.utils.android.Permissions;
import me.android.library.utils.android.PreferenceUtil;
import mylab.base.foundation.lang.Callback;

@Slf4j
@UtilityClass
public class DownloadUtil {

    public interface DownloadListener {
        void onDownloadCompleted(Uri uri);
    }

    private final static String SubPath = Environment.DIRECTORY_DOWNLOADS;

    public DownloadTask newFileDownloadTask(Activity cx, String key, String url, DownloadListener listener) {
        return new DownloadTask(cx, key, url, listener);
    }

    public AppDownloadTask newAppDownloadTask(Activity cx, String key, String url) {
        return new AppDownloadTask(cx, key, url);
    }


    public static class AppDownloadTask extends DownloadTask {

        public AppDownloadTask(Activity cx, String key, String downUrl) {
            super(cx, key, downUrl, null);
        }

        @Override
        protected void onFinished(@NonNull Uri uri) {
            if (cx instanceof Activity activity) {
                InstallUtil.installApk(activity, uri);
            } else {
                InstallUtil.installApk(cx, uri);
            }
        }
    }

    public static class DownloadTask extends BroadcastReceiver {

        Context cx;
        DownloadManager dm;
        SharedPreferences prefs;
        String key;
        String downUrl;
        boolean hasPermit;
        DownloadListener listener;

        public DownloadTask(Activity cx, String key, String downUrl, DownloadListener listener) {
            this.cx = cx;
            this.key = key;
            this.downUrl = downUrl;
            this.listener = listener;

            dm = (DownloadManager) cx.getSystemService(Context.DOWNLOAD_SERVICE);
            prefs = PreferenceUtil.getDefaultPrefs();
            hasPermit = PermissionUtil.hasPermissions(cx, Permissions.ACCESS_DOWNLOAD_MANAGER);
        }

        @Override
        public void onReceive(Context cx, Intent intent) {
            // 这里可以取得下载的id，这样就可以知道哪个文件下载完成了。适用与多个下载任务的监听
            long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
            if (prefs.getLong(key, 0) == id) {
                if (Objects.equals(intent.getAction(), DownloadManager.ACTION_DOWNLOAD_COMPLETE)) {
                    cx.unregisterReceiver(this);
                    Uri uri = dm.getUriForDownloadedFile(id);
                    onFinished(uri);
                }
            }
        }

        protected void onFinished(Uri uri) {
            if (listener != null) {
                listener.onDownloadCompleted(uri);
            }
        }

        public void download(String fileName) throws Exception {
            download(fileName, null);
        }

        public void download(String fileName, String titleOnNotification) throws Exception {

            if (hasPermit) {
                download(fileName, titleOnNotification, null);
            } else {
                downloadByHttp(fileName);
            }
        }

        public void download(String fileName, String titleOnNotification, String descriptionOnNotification) throws Exception {

            String url = downUrl;
            Uri uri = Uri.parse(url);

            DownloadManager.Request request = new DownloadManager.Request(uri);
            request.setAllowedNetworkTypes(Request.NETWORK_MOBILE | Request.NETWORK_WIFI);

            request.allowScanningByMediaScanner();
            request.setAllowedOverRoaming(true);
            // 设置文件类型
            MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
            String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url));
            request.setMimeType(mimeString);
            // 在通知栏中显示
            request.setNotificationVisibility(Request.VISIBILITY_VISIBLE);
            // request.setShowRunningNotification(true);// 默认是true，改为false需要权限
            request.setVisibleInDownloadsUi(true);
            request.setTitle(titleOnNotification);
            request.setDescription(descriptionOnNotification);

            // sdcard的目录下的download文件夹
            request.setDestinationInExternalPublicDir(SubPath, fileName);
            ContextCompat.registerReceiver(cx, this, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE), ContextCompat.RECEIVER_NOT_EXPORTED);
            dm = (DownloadManager) cx.getSystemService(Context.DOWNLOAD_SERVICE);

            try {
                long id = dm.enqueue(request);

                // 保存id
                prefs = PreferenceUtil.getDefaultPrefs();
                prefs.edit().putLong(key, id).apply();
            } catch (Exception e) {
                log.warn("save key to SharedPreferences error", e);
                throw e;
            }
        }

        private void downloadByHttp(String fileName) {
            RestfulService.getInstance().downFile(downUrl, fileName, Callback.simple(this::onFinished));
        }
    }

}
